using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Compilation;
using System.CodeDom;
using System.Web;

namespace AspNetExtensions.ExpressionBuilders
{
    [ExpressionPrefix("Profile")]
    public class ProfileExpressionBuilder : ExpressionBuilder
    {
        // Parse the expression's arguments
        public override object ParseExpression(string expression, Type propertyType, ExpressionBuilderContext context)
        {
            return expression;
        }

        public override CodeExpression GetCodeExpression(
            System.Web.UI.BoundPropertyEntry entry, 
            object parsedData, 
            ExpressionBuilderContext context)
        {
            // Grab the name of the profile property
            if (!(parsedData is string))
                return null;

            string property = (string)parsedData;

            // Must generate code for the right-side of an assignment
            // We make it call into a static method of this class

            // Define the CodeDOM object that represents the
            // parameter of the static method
            CodePrimitiveExpression prim = new CodePrimitiveExpression(property);
            CodeExpression[] args = new CodeExpression[1] { prim };

            // Define the CodeDOM object to represent the method invocation
            CodeTypeReferenceExpression refType;
            refType = new CodeTypeReferenceExpression(base.GetType());
            return new CodeMethodInvokeExpression(refType, "GetProperty", args);
        }

        public static object GetProperty(string propertyName)
        {
            return HttpContext.Current.Profile.GetPropertyValue(propertyName);
        }

        public override object EvaluateExpression(object target, System.Web.UI.BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
        {
            // "parsedData" gets what ParseExpression returns
            string propName = (string)parsedData;
            return GetProperty(propName);
        }

        public override bool SupportsEvaluate
        {
            get
            {
                return true;
            }
        }
    }
}
